/*
	Exemplos para compreendimento da função: memset
	pode ser compilado.
*/

#include <stdio.h>		// fprintf, fscanf
#include <stdlib.h>		// malloc, free
						// void exit(EXIT_FAILURE);
						// void exit(EXIT_SUCCESS);
						// rand, srand
						// atoi, atof
						// NULL
						// qsort, bsearch (implementar uma função de comparação,
						// semelhante ao strcmp e passar por parâmetro
						
#include <sys/types.h>	// complemento para o cabeçalho abaixo sys/socket.h
#include <sys/socket.h> // socket, bind
#include <netdb.h>		// addrinfo
#include <arpa/inet.h>

//	cabeçalhos:
#include <string.h>		// memset
						// funções de manipulação de string

//	exemplo:
//	Utiliza o memset para limpar estruturas addrinfo.
//	Depois faz testes com funções getaddrinfo, socket, close

#define SUCESSO
int main() {

	int sockfd, status, closed;
	
	// informações relevantes
	struct addrinfo hints;
	
	// armazenar o resultado do getaddrinfo
	struct addrinfo *res;
	
	// preencher com zero.
	memset(&hints, 0, sizeof hints );
	
	// CUIDADO: ao usar com ponteiros, deve ser chamado depois do malloc:
	size_t len_addrinfo = sizeof(struct addrinfo); // para representar tamanho é recomendável o uso do size_t.
	res = malloc(len_addrinfo); // Obs.: para alocar vetor usar calloc
	
	if(res == NULL)	//	malloc retorna NULL se não houver memória para alocar
		fprintf(stderr, "Erro gravíssimo: memória cheia...");
	
	memset(res, 0, len_addrinfo);
	

	// faz o lookup [com o hints já preenchido]
#ifdef SUCESSO
	if( status = getaddrinfo("facom.ufms.br", "http", &hints, &res) != 0 ) {
#else
	if( status = getaddrinfo("aimeudeus", "http", NULL, &res) != 0 ) {
#endif
	
		// tratamento de erro
		fprintf(stderr, "getaddrinfo error:\t\t%s\n", gai_strerror(status));
	} //endif

	sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);	
	
	printf("retorno do getaddrinfo():\t%d\n", status);
	printf("retorno do socket():\t\t%d\n", sockfd);

	closed = close(sockfd);
	
	// libera recursos apontados pelo ponteiro res
	free(res);
	res = NULL;	// sempre anular o ponteiro depois do free.
				// TO DO: criar uma função para liberar ponteiro que chama o malloc e faz verificação

	printf("retorno do close():\t\t%d\n", closed);
	printf("sockfd depois do close:\t\t%d\n", sockfd);

}
/*
	- saída do programa em caso de sucesso:
	retorno do getaddrinfo():	0
	retorno do socket():		3
	retorno do close():			0
	sockfd depois do close:		3

	- saída do programa em caso de erro:
	getaddrinfo error:			Unknown error
	retorno do getaddrinfo():	1
	retorno do socket():		-1
	retorno do close():			-1
	sockfd depois do close:		-1

*/
